/**
 * Customized photo list, only allow vertical direction scroll, maintain Photo objects.
 * Photo object load from PhotoStore which hold all Photo object models, 
 * 
 * You only care about configs and API below:  
 * 
 * config:{
 		enableDebug: false,			// Controll the console.log output, default is false
 		showBorderRadius: false,	// Show photo border radius effect
		showShadow: true,			// Show photo shadow effect
		showTitle: false,			// Show photo title text
		photoWidth: '200px'			// Photo component size
		photoHeight: '200px'		// Photo component size
		showTestingBar: false		// Show the testing titlebar and toolbar, see desc below
 * }
 * 
 * API:  
 * 1. {@link PhotoList.view.PhotoList#addPhoto addPhoto : Add a photo component into list}    
 * 2. {@link PhotoList.view.PhotoList#removePhoto removePhoto : Remove a photo component from list}    
 * 3. {@link PhotoList.view.PhotoList#clearPhoto clearPhoto : Remove all photo components from list( also destroy binding model instance )}    
 * 4. {@link PhotoList.view.PhotoList#toggleEditMode toggleEditMode : Toggle mode( normal/editting )}  
 * 5. {@link PhotoList.view.PhotoList#deleteSelectedPhotos deleteSelectedPhotos : Delete selected photo component from list( usually only call in edit mode )}  
 *    		
 * Event Hanlder:   
 * 1. {@link PhotoList.view.PhotoList#onPhotoTaped onPhotoTaped}     
 * 2. {@link PhotoList.view.PhotoList#onPhotoListSelectChanged onPhotoListSelectChanged}  
 * 3. {@link PhotoList.view.PhotoList#onSettingChanged_ShowBorderRadius onSettingChanged_ShowBorderRadius}  
 * 4. {@link PhotoList.view.PhotoList#onSettingChanged_ShowShadow onSettingChanged_ShowShadow}  
 * 5. {@link PhotoList.view.PhotoList#onSettingChanged_ShowTitle onSettingChanged_ShowTitle}  
 * 6. {@link PhotoList.view.PhotoList#onSettingChanged_Size onSettingChanged_Size}  
 * 7. {@link PhotoList.view.PhotoList#onSettingChanged_ShowTestingBar onSettingChanged_ShowTestingBar}  
 *   
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * For testing purpose, it has:  
 * 
 * 1. Top titlebar: place toggle mode button  
 *    Toggle edit mode: change photo's tap behavior:  
 * 			A) Normal mode: tap photo to fire event "PhotoList.model.UserEvent.onPhotoTaped"  
 * 			B) Edit mode: tap photo to toggle photo's selection, fire event "PhotoList.model.UserEvent.onPhotoListSelectChanged"        
 *
 *
 * 2. Bottom toolbar: place delete button( delete all selected photo )  
 *   
 * <h3>Attention: The titlebar/toolbar UI just show you the features of PhotoList component( events and API ), you can remove them after you know about that</h3>  
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * 
 * @author:		wison ye
 * @version:	1.0
 */
Ext.define( 'PhotoList.view.PhotoList', {
	extend: 'Ext.Container',
	alias: 'widget.photo_list',
	requires: [
	           'PhotoList.model.UserEvent',
	           'PhotoList.view.Photo',
	           'PhotoList.store.PhotoStore'
    ],
	config: {
		/*
		 * Store hold all the photo models
		 */
		store: '',
		
		/**
		 * Controll console.log output
		 */
		enableDebug: true,
		
		/**
		 * Enable or disable UI cls: border radius effect
		 */
		showBorderRadius: true,
		
		/**
		 * Enable or disable UI cls: shadow effect
		 */
		showShadow: true,
		
		/**
		 * Enable or disable UI cls: photo title effect
		 */
		showTitle: true,
		
		/**
		 * Photo size: width, for example: '100px'
		 */
		photoWidth: '100px',
		
		/**
		 * Photo size: height, for example: '100px'
		 */
		photoHeight: '100px',
		
		/*
		 * Only can scroll in vertical
		 */ 
		scrollable: {
		    direction: 'vertical',
		    directionLock: true
		},
		
//		layout: 'auto',
		
		/*
		 * Is it in edit mode
		 */
		editMode: false,
		
		/**
		 * Show testing bar
		 */
		showTestingBar: false,
		
		/*
		 * Functional test bar, controll by "showTestingBar"
		 */
		items: [{
	        docked: 'top',
	        xtype: 'titlebar',
	        title: '我的应用',
	        itemId: 'testingTitlebar',
	        hidden: true,
			items:[{
				xtype: 'segmentedbutton',
				align: 'right',
				allowDepress: true, 
				itemId: 'btnToggleEditMode',
				items:[{
					iconMask: true,
					iconCls: 'compose'
				}]
			}]
		},{
			docked: 'bottom',
			xtype: 'toolbar',
			itemId: 'testingToolbar',
			hidden: true,
			layout: {
	            align: 'center',
	            pack: 'center',
	            type: 'hbox'
			},
			items:[{
				iconMask: true,
				iconCls: 'trash',
				iconAlign: 'center', 
//				text: 'Delete',
				ui: 'decline',
				itemId: 'btnDelete',
				disabled: true,
				width: '150px'
//				margin: '0 20 0 20'
			}]
		}],
		
		listeners: [{
			fn: 'onPainted',
			event: 'painted'
		},{
			fn: 'onInitialize',
			event: 'initialize'
		},{
	 		fn: 'onEditModeToggleTap',
	 		event: 'toggle',
	 		delegate: '#btnToggleEditMode'
	 	},{
	 		fn: 'onBtnDeleteTap',
	 		event: 'tap',
	 		delegate: '#btnDelete'
	 	}],
	 	
	 	/*
	 	 * Hold the last selected photos
	 	 */
	 	lastSelectedPhotosList: [],
	 	
	 	/*
	 	 * Hold the btnDelete button
	 	 */
	 	btnDeleteRef: null
	},
	
	/*------------------------------------------------------------------------------------------
	 * Override constructor
	 *------------------------------------------------------------------------------------------*/
	constructor: function( config ){
		this.callParent( arguments );
		
		this.addListener( PhotoList.model.UserEvent.onPhotoListSelectChanged , this.onPhotoListSelectChanged );
		this.addListener( PhotoList.model.UserEvent.onPhotoTaped , this.onPhotoTaped );
		
		this.addListener( PhotoList.model.UserEvent.onSettingChanged_ShowBorderRadius, this.onSettingChanged_ShowBorderRadius );
		this.addListener( PhotoList.model.UserEvent.onSettingChanged_ShowShadow, this.onSettingChanged_ShowShadow );
		this.addListener( PhotoList.model.UserEvent.onSettingChanged_ShowTitle, this.onSettingChanged_ShowTitle );
		this.addListener( PhotoList.model.UserEvent.onSettingChanged_Size, this.onSettingChanged_Size );
		this.addListener( PhotoList.model.UserEvent.onSettingChanged_ShowTestingBar, this.onSettingChanged_ShowTestingBar );
		
		if ( this.store == null ){
			this.setStore( Ext.create( 'PhotoList.store.PhotoStore' ) );
		}
		
		/*
		 * Guarantee not in edit mode at the beginning( although you put "editMode:true" in config )!!!
		 */
		this.setEditMode( false );
	},
	
	/*--------------------------------------------------------------------------------------------------------
	 * onInitialize: show testing bar if need
	 * 
	 * @param	{Ext.Component}	compRef
	 * @param	{Object}		options
	 *--------------------------------------------------------------------------------------------------------*/
	onInitialize: function( compRef, options ){
		 if ( this.getEnableDebug() ) console.log( 'PhotoList.onInitialize' );
		 
		 if ( this.getShowTestingBar() ){
			 var testTitlebarRef = this.down( '#testingTitlebar' );
			 if ( testTitlebarRef != null ){
				 testTitlebarRef.show();
			 }
//			 var testToolbarRef = this.down( '#testingToolbar' );
//			 if ( testToolbarRef != null ){
//				 testToolbarRef.show();
//			 }			 
		 }
		 
		 /*
		  * Get btnDelete reference
		  */
		 var btnDeleteRefArr = this.query( '#btnDelete' );
		 this.setBtnDeleteRef( btnDeleteRefArr[0] );
	},
	 
    /*------------------------------------------------------------------------------------------
     * Reload test photos to fill the list 
     *------------------------------------------------------------------------------------------*/
	onPainted: function(){
    	 if ( this.getEnableDebug() ) console.log( 'PhotoList.onPainted' );
    	 this.reLoadTestPhotos();
	},
	
	/*------------------------------------------------------------------------------------------*/
	/**
	 * Add a photo
	 * 
	 * @param	{String}	photoUrl
	 * @param	{String}	titleText
	 */
	addPhoto: function( photoUrl, titleText ){
		 var newModel = Ext.create( 'PhotoList.model.Photo', {
			 url: photoUrl,
			 title: '<center>' + titleText + '</center>'
		 });
		 
		 var newPhoto = Ext.create( 'PhotoList.view.Photo', {
			 model: newModel,
			 showBorderRadius: this.getShowBorderRadius(),
			 showShadow: this.getShowShadow(),
			 showTitle: this.getShowTitle(),
			 width: this.getPhotoWidth(),
		 	 height: this.getPhotoHeight(),
		 	 enableDebug: this.getEnableDebug()
		 });
		 
		 this.getStore().add( newModel );
		 
		 this.add( newPhoto );
	},
	 
	/*------------------------------------------------------------------------------------------*/
	/**
	 * Remove a photo
	 * 
	 * @param	{PhotoList.view.Photo}	photoRef
	 */
	removePhoto: function( photoRef ){
		 if ( photoRef == null ) return;
		 
		 if ( photoRef.getModel() != null ){
			 this.getStore().remove( photoRef.getModel() );
		 }
		 
		 this.remove( photoRef, true );
	},
	
	/*------------------------------------------------------------------------------------------*/
	/**
	 * Remove all photos
	 */
	clearPhoto: function(){
		 this.getStore().removeAll( true );
		 if ( this.getEnableDebug() ){
			 console.log( 'remove all photo models from store.' );
		 }
			 
		 
		 this.removeAll( true, false );
		 if ( this.getEnableDebug() ){
			 console.log( 'remove all photo components from photo list.' );
		 }
	},
	
//	/**------------------------------------------------------------------------------------------
//	 * Remove a photo
//	 * 
//	 * @param	{String}	photoUrl
//	 *------------------------------------------------------------------------------------------*/
//	removePhoto: function( photoUrl ){
//		 if ( photoUrl == null || photoUrl.trim() == '' ) return;
//		 
//		 this.getStore().remove( this.getStore.findRecord( 'url', photoUrl ) );
//	},

	/*------------------------------------------------------------------------------------------*/
	/**
	 * Toggle edit mode:  
	 * 
 	 * A) Normal mode: tap photo to fire event "PhotoList.model.UserEvent.onPhotoTaped"    
 	 * B) Edit mode: tap photo to toggle photo's selection, fire event "PhotoList.model.UserEvent.onPhotoListSelectChanged"        
	 */
	toggleEditMode: function(){
		 this.setEditMode( !this.getEditMode() );
		 
		 var tips;
		 var testToolbarRef = this.down( '#testingToolbar' );
		 if ( this.getEditMode() ){
			 if ( this.getEnableDebug() ) console.log( 'Edit mode.' );
			 
			 var componentsArr = this.getItems();
			 Ext.each( componentsArr.items, function( component ){
				 
				 if ( component.xtype == 'photo' ){
					 component.setInEditMode( true );
				 }
				 
			 }, this );
			 
			 // show toolbar
			 testToolbarRef.show();
			 tips = 'Tap photo to fire "onPhotoListSelectChanged" event';
		 }
		 else{
			 if ( this.getEnableDebug() ) console.log( 'Cancel Edit mode.' );
			 
			 // Unselect all photos ( if selected )
			 var componentsArr = this.getItems();
			 Ext.each( componentsArr.items, function( component ){
				 
				 if ( component.xtype == 'photo' ){
					 component.CancelSelection();
					 component.setInEditMode( false );
				 }
				 
			 }, this );
			 
			 // hide toolbar
			 testToolbarRef.hide();
			 tips = 'Tap photo to fire "onPhotoTap" event';
		 }
		 Ext.Msg.alert( 'Tips', tips, Ext.emptyFn );
		 
		 this.getBtnDeleteRef().disable();
	},
	
	/*------------------------------------------------------------------------------------------*/
	/**
	 * onPhotoListSelectChanged event handler
	 * 
	 * @param	{PhotoList.view.Photo}	photoRef
	 */
	onPhotoListSelectChanged: function( photoRef ){
		 if ( this.getEnableDebug() ){
			 console.log( 'onPhotoListSelectChanged, url:' + photoRef.getModel().get( 'url' ) + ', selected:' + photoRef.getModel().get( 'selected' ) + ' )' );
		 }
		 
		 var selected = photoRef.getModel().get( 'selected' );
		 if ( selected ){
			 Ext.Array.include( this.getLastSelectedPhotosList(), photoRef );
		 }
		 else{
			 Ext.Array.remove( this.getLastSelectedPhotosList(), photoRef );
		 }
		 
		 /*
		  * Controll delete button status
		  */
		 if ( Ext.isEmpty( this.getLastSelectedPhotosList() ) ){
			 this.getBtnDeleteRef().disable();
		 }
		 else{
			 this.getBtnDeleteRef().enable();
		 }
		 
		 
	},

	/*------------------------------------------------------------------------------------------*/
	/**
	 * onPhotoTaped event handler
	 * 
	 * @param	{PhotoList.view.Photo}	photoRef
	 */
	onPhotoTaped: function( photoRef ){alert(photoRef.getModel().get('title'))
		Ext.Anim.run( photoRef.element, 'fade', {
		    duration: 100
		});
	},

    /*------------------------------------------------------------------------------------------
     * Reload test photos to fill the list 
     *------------------------------------------------------------------------------------------*/
	reLoadTestPhotos: function(){
        this.clearPhoto();
        Ext.Ajax.request({
            url: 'js/PhotoList/app/store/photoData.json',
            scope:this,
            success: function(response){
                var text = response.responseText;
                o=Ext.JSON.decode(text)
                for(i=0;i<o.items.length;i++){
                    this.addPhoto( o.items[i].url,  o.items[i].title );
                }
            }
        });





    	 /*var photoCount = 20;
    	 this.clearPhoto();

    	 for(var index=1; index<=photoCount; index++) {
    		 var url = 'resources/images/' + String( index ) + '.jpg';
    		 var title = String( index );
    		 this.addPhoto( url, title );
    	 }*/
	},
	
	/*------------------------------------------------------------------------------------------
	 * onEditModeToggleTap  
	 * 
	 * @param	{Ext.SegmentedButton}	sbRef
	 * @param	{Ext.Button}			btnEditModeRef , 
	 * @param	{Boolean}				isPressed
	 *------------------------------------------------------------------------------------------*/
	onEditModeToggleTap: function( sbRef, btnEditModeRef, isPressed ){
		// console.log( 'toggle, isPressed: ' + isPressed );
		this.toggleEditMode();
	},

	/*------------------------------------------------------------------------------------------
	 * onBtnDeleteTap 
	 *   
	 * @param	{Ext.Button}	btnRef
	 *------------------------------------------------------------------------------------------*/
	onBtnDeleteTap: function( btnRef ){
		 var actionSheet = Ext.create( 'Ext.ActionSheet', {
			stretchX: true, 
			stretchY: false,
		    items: [
		        {
		            text: 'Delete Selected Photos',
		            ui: 'decline',
		            listeners: {
		        		scope: this,
		        		tap: function( btnRef ){
		        			var asRef = btnRef.up( 'actionsheet' );
		        			this.deleteSelectedPhotos( asRef );
		        		}
		        	}
		        },
		        {
		            text: 'Cancel',
		            ui: 'confirm',
		            listeners: {
		        		tap: function( btnRef ){
		        			var asRef = btnRef.up( 'actionsheet' );
		        			asRef.hide();
		        			asRef.destroy();
		        		}
		        	}
		        }
		    ]
		});
		Ext.Viewport.add( actionSheet );
		actionSheet.show(); 
	},
	
	/*------------------------------------------------------------------------------------------*/
	/**
	 * Delete selected photos 
	 * 
	 * @param	{Ext.ActionSheet}	asRef
	 */
	deleteSelectedPhotos: function( asRef ){
		 asRef.hide();
		 asRef.destroy();
		 
		 if ( !Ext.isEmpty( this.getLastSelectedPhotosList() ) ){
			 
			 Ext.Array.each( this.getLastSelectedPhotosList(), function( photoRef ){
				 this.removePhoto( photoRef );				 
			 }, this );
			 
			 this.getLastSelectedPhotosList().length = 0;
			 this.getBtnDeleteRef().disable();
		 }
	},
	
	/*------------------------------------------------------------------------------------------*/
	/**
	 * onSettingChanged_ShowBorderRadius 
	 * 
	 * @param	{Boolean}	isShow
	 */
	onSettingChanged_ShowBorderRadius: function( isShow ){
		if ( this.getEnableDebug() ) console.log( 'onSettingChanged_ShowBorderRadius, isShow:' + isShow );
		
		this.setShowBorderRadius( isShow );
		var componentsArr = this.getItems();
		 Ext.each( componentsArr.items, function( component ){
			 
			 if ( component.xtype == 'photo' ){
				 component.switchBorderRadiusCls( isShow );
			 }
			 
		 }, this );
		 
		 this.getParent().previous();
	},

	/*------------------------------------------------------------------------------------------*/
	/**
	 * onSettingChanged_ShowShadow 
	 * 
	 * @param	{Boolean}	isShow
	 */
	onSettingChanged_ShowShadow: function( isShow ){
		 if ( this.getEnableDebug() ) console.log( 'onSettingChanged_ShowShadow, isShow:' + isShow );
		 
		 this.setShowShadow( isShow );
		 var componentsArr = this.getItems();
		 Ext.each( componentsArr.items, function( component ){
			 
			 if ( component.xtype == 'photo' ){
				 component.switchShadowCls( isShow );
			 }
			 
		 }, this );
		 
		 this.getParent().previous();	 
	},	 

	/*------------------------------------------------------------------------------------------*/
	/**
	 * onSettingChanged_ShowTitle 
	 * 
	 * @param	{Boolean}	isShow
	 */
	onSettingChanged_ShowTitle: function( isShow ){
		 if ( this.getEnableDebug() ) console.log( 'onSettingChanged_ShowTitle, isShow:' + isShow );
		
		 var componentsArr = this.getItems();
		 Ext.each( componentsArr.items, function( component ){
			 
			 if ( component.xtype == 'photo' ){
				 component.switchTitle( isShow );
			 }
			 
		 }, this );
		 
		 this.getParent().previous();	
	},
	 
	/*------------------------------------------------------------------------------------------*/
	/**
	 * onSettingChanged_Size 
	 * 
	 * @param	{String}	newSize
	 */
	onSettingChanged_Size: function( newSize ){
		 if ( this.getEnableDebug() ) console.log( 'onSettingChanged_Size, newSize:' + newSize );
		
		 var componentsArr = this.getItems();
		 Ext.each( componentsArr.items, function( component ){
			 
			 if ( component.xtype == 'photo' ){
				 component.ChangeSize( newSize );
			 }
			 
		 }, this );
		 
		 this.getParent().previous();	
	},
	 
	/*------------------------------------------------------------------------------------------*/
	/**
	 * onSettingChanged_ShowTestingBar 
	 * 
	 * @param	{Boolean}	isShow
	 */
	onSettingChanged_ShowTestingBar: function( isShow ){
		 if ( this.getEnableDebug() ) console.log( 'onSettingChanged_ShowTestingBar, isShow:' + isShow );
		
		 this.setShowTestingBar( isShow );
		 var testTitlebarRef = this.down( '#testingTitlebar' );
		 if ( testTitlebarRef != null ){
			 if ( isShow )
				 testTitlebarRef.show();
			 else
				 testTitlebarRef.hide();
		 }
		 
		 this.getParent().previous();	
	}
	
});
